home *** CD-ROM | disk | FTP | other *** search
- // This is the code graphic system's kernel
- // Written by Kiselev J., CZ 1994.
-
- #pragma -ml
-
- #include <conio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <mem.h>
- #include <dos.h>
-
- #include "graph.h"
-
- //borland's default patterns
- const char CZsign[] = "^Z Graphics Library. Control Zed Ltd. (c) 1993-94";
- BYTE patterns[12][8] = {{0,0,0,0,0,0,0,0},
- {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
- {0xff,0xff,0,0,0xff,0xff,0,0},
- {1,2,4,8,0x10,0x20,0x40,0x80},
- {0xe0,0xc1,0x83,7,0xe,0x1c,0x38,0x70},
- {0xf0,0x78,0x3c,0x1e,0xf,0x87,0xc3,0xe1},
- {0xa5,0xd2,0x69,0xb4,0x5a,0x2d,0x96,0x4b},
- {0xff,0x88,0x88,0x88,0xff,0x88,0x88,0x88},
- {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81},
- {0xcc,0x33,0xcc,0x33,0xcc,0x33,0xcc,0x33},
- {0x80,0,8,0,0x80,0,8,0},
- {0x88,0,0x22,0,0x88,0,0x22,0}};
-
- //borlands's line styles
- WORD solidline = 0xffff;
- WORD dottedline = 0xcccc;
- WORD centerline = 0xfc78;
- WORD dashedline = 0xf8f8;
-
- typedef char str[13];
- const str arraymodenames[11] = {"640x350 16",
- "640x480 16",
- "320x200 256",
- "800x600 16",
- "640x400 256",
- "640x480 256",
- "800x600 256",
- "1024x768 16",
- "1024x768 256",
- "1280x1024 16",
- "1280x1024 256"};
- typedef struct
- {
- int width;
- int height;
- WORD bytesperline;
- BYTE BIOSmode;
- WORD VESAmode;
- BYTE modenum;
- BYTE VESAgrwinshift;
- } modetype;
-
- modetype arraymodeset[11] = {{640,350,80,0x10,0,0},
- {640,480,80,0x12,0,1},
- {320,200,320,0x13,0,2},
- {800,600,100,0,0x102,3},
- {640,400,640,0,0x100,4},
- {640,480,640,0,0x101,5},
- {800,600,800,0,0x103,6},
- {1024,768,128,0,0x104,7},
- {1024,768,1024,0,0x105,8},
- {1280,1024,160,0,0x106,14},
- {1280,1024,1280,0,0x107,15}};
- const NormalPut = 0;
- const AndPut = 1 << 3;
- const OrPut = 2 << 3;
- const XORPut = 3 << 3;
-
- BOOL drawpoly_in_fillpoly = TRUE;
- modelisttype modelist;
- modetype activemode;
-
- BYTE mono,oldmode;
- int currx,curry;
- linesettingstype linetype;
- BYTE* userpatternptr;
- BOOL graph_is_ready = FALSE;
-
- const char VESAcall = 0x4f;
- const char VESAsign[4] = "VESA";
-
- //VESA Control function
- const char getVESAinfo = 0;
- const char getmodeinfo = 1;
- const char setVESAmode = 2;
- const char getVESAmode = 3;
- const char SVGAstate = 4;
- const char swichbank = 5;
-
- enum proc_offsets {
- indexputpixel,
- indexdrawline,
- indexbar,
- indexputimage,
- indexgetimage,
- indeximagesize,
- indexputrow,
- indexdrawpolygon,
- indexchangeput,
- indexgetpixel
- };
-
- extern "C" WORD testadapter(void);
- extern "C" void normalline(int x1,int y1,int x2,int y2);
- extern "C" BYTE clippixel(int x,int y);
-
- extern viewporttype viewport;
- extern viewporttype viewport32767;
- extern WORD videoselector;
- extern WORD bytesperline;
- extern WORD linepattern;
- extern BYTE* fillpatternptr;
- extern patterntype;
- extern trflag;
- extern BYTE drawcolor;
- extern BYTE fillcolor;
- extern BYTE backcolor;
- extern BYTE writemode;
- extern int *ArrayScanLinesPtr;
- extern WORD sizeonerow;
- extern void *far callVESAswbnkptr;
- extern BYTE grshift;
-
- extern proctable16;
- extern proctable256;
- extern proctables256;
-
- void *far proctable = &proctable16;
-
- void (*line)(int x1,int y1,int x2,int y2);
-
- int SVGAsearch(void)
- {
- BYTE mcount,i;
- WORD mode,j;
- struct {
- char VESAsignature[4];
- WORD VESAversion;
- char far *OEMstringptr;
- long capabilities;
- int far *videomodeptr;
- BYTE reserved[238];
- } VESAinfo;
- struct {
- WORD modeattributes;
- BYTE winAattributes;
- BYTE winBattributes;
- WORD wingranularity;
- WORD winsize;
- WORD winAsegment;
- WORD winBsegment;
- void *winfuncptr;
- WORD bytesperscanline;
- // end of obligatory structure
- WORD Xresolution;
- WORD Yresolution;
- BYTE Xcharcellsize;
- BYTE Ycharcellsize;
- BYTE numberofplanes;
- BYTE bitsperpixel;
- BYTE numberofbanks;
- BYTE memorymodel;
- BYTE banksize;
- BYTE reserved[227];
- } modeinfo;
-
- asm {
- mov ax,ss
- mov es,ax
- lea di,VESAinfo
- mov ah,VESAcall
- mov al,getVESAinfo
- int 10h
- }
- if (_AX != 0x4F) return(-1);
- if (_fmemcmp(MK_FP(_ES,_DI),VESAsign,4) != 0) return(-1);
- while(*VESAinfo.videomodeptr != -1)
- {
- asm {
- les di,dword ptr VESAinfo.videomodeptr
- mov cx,es:[di]
- mov mode,cx
- mov ax,ss
- mov es,ax
- lea di,modeinfo
- mov ah,VESAcall
- mov al,getmodeinfo
- int 10h
- add word ptr VESAinfo.videomodeptr[0],2 //offset next mode
- }
- if (_AX != 0x4f) continue;
- if ((modeinfo.modeattributes & 0x10) == 0) continue; // It is a graphics mode
- for(j=1;j<=modecounter;j++)
- {
- if (arraymodeset[j].VESAmode == mode)
- {
- modelist.modes[modelist.numberofmodes].mode = j;
- memcpy(modelist.modes[modelist.numberofmodes].name,
- arraymodenames[j],sizeof(arraymodenames[0]));
- if (modeinfo.winfuncptr != NULL) callVESAswbnkptr = modeinfo.winfuncptr;
- if (modeinfo.bytesperscanline != arraymodeset[j].bytesperline)
- arraymodeset[j].bytesperline = modeinfo.bytesperscanline;
- switch (modeinfo.wingranularity)
- {
- case 64 : arraymodeset[j].VESAgrwinshift=0; break;
- case 32 : arraymodeset[j].VESAgrwinshift=1; break;
- case 16 : arraymodeset[j].VESAgrwinshift=2; break;
- case 8 : arraymodeset[j].VESAgrwinshift=3; break;
- case 4 : arraymodeset[j].VESAgrwinshift=4; break;
- case 1 : arraymodeset[j].VESAgrwinshift=5; break;
- default : printf("Internal error.\a"); //oops
- }
- modelist.numberofmodes++;
- break;
- }
- }
- }
- return(0);
- }
-
- int graphinit(void)
- {
- WORD device;
- asm mov ah,0xf
- asm int 0x10
- asm mov oldmode,al
- device = testadapter();
- switch (device >> 8)
- {
- case -1 : return(-1);
- case 2 : mono = TRUE;
- }
- switch (device & 0x00ff)
- {
- case -1 : return(-1);
- case 3 :
- {
- // standart VGA modes : (640x350x16) 640x480x16 or 320x200x256
- activemode = arraymodeset[VGA16];
- modelist.modes[0].mode = EGA16;
- memcpy(modelist.modes[0].name,
- arraymodenames[EGA16],sizeof(arraymodenames[0]));
- modelist.modes[1].mode = VGA16;
- memcpy(modelist.modes[1].name,
- arraymodenames[VGA16],sizeof(arraymodenames[0]));
- modelist.modes[2].mode = VGA256;
- memcpy(modelist.modes[2].name,
- arraymodenames[VGA256],sizeof(arraymodenames[0]));
- modelist.numberofmodes += 3;
- // check VESA BIOS extention
- SVGAsearch();
- }; break;
- case 2 :
- {
- activemode = arraymodeset[EGA16];
- modelist.modes[0].mode = EGA16;
- memcpy(modelist.modes[0].name,
- arraymodenames[EGA16],sizeof(arraymodenames[0]));
- }
- }
- _AH = 0;
- _AL = activemode.BIOSmode;
- geninterrupt(0x10);
- // default settings
- setviewport(0,0,activemode.width-1,activemode.height-1);
- line = normalline;
- drawcolor = fillcolor = WHITE;
- backcolor = BLACK;
- bytesperline = activemode.bytesperline;
- linepattern = 0xffff;
- if ((ArrayScanLinesPtr = (int *) malloc(activemode.height*sizeonerow)) == NULL)
- {
- printf("Not enough memory to allocate buffer\n"); // for fillpoly routine
- return(-1); // terminate program if out of memory
- }
- graph_is_ready = TRUE;
- return(0);
- }
-
- int switchmode(int mode)
- {
- int i;
- if (!graph_is_ready) return(-1);
- if (mode != activemode.modenum)
- {
- for(i=0;i<=modelist.numberofmodes;i++)
- if (mode == modelist.modes[i].mode)
- {
- if (arraymodeset[i].BIOSmode != 0)
- {
- activemode = arraymodeset[mode];
- _AH = 0;
- _AL = activemode.BIOSmode;
- geninterrupt(0x10);
- }
- else
- {
- activemode = arraymodeset[mode];
- _AH = VESAcall;
- _AL = setVESAmode;
- _BX = activemode.VESAmode;
- geninterrupt(0x10);
- }
- i = -1;
- break;
- }
- }
- if (i != -1) return(-1);
- else
- {
- free(ArrayScanLinesPtr);
- if ((ArrayScanLinesPtr = (int *) malloc(activemode.height*sizeonerow)) == NULL)
- {
- printf("Not enough memory to allocate buffer\n");
- return(-1); // terminate program if out of memory
- }
- // default settings
- setviewport(0,0,activemode.width-1,activemode.height-1);
- line = normalline;
- drawcolor = 15;
- fillcolor = 15;
- backcolor = 0;
- bytesperline = activemode.bytesperline;
- linepattern = 0xffff;
- switch (mode) {
- case EGA16 : proctable = &proctable16; break;
- case VGA16 : proctable = &proctable16; break;
- case VGA256 : proctable = &proctable256; break;
- case SVGA640x400x256 :
- case SVGA640x480x256 :
- case SVGA800x600x256 :
- case SVGA1024x768x256 :
- case SVGA1280x1024x256 : proctable = &proctables256;
- }
- grshift = arraymodeset[mode].VESAgrwinshift;
- return(0);
- }
- }
-
- void setviewport(int x1,int y1,int x2,int y2)
- {
- // add 32768 for fast clip lines (integer to word)
- viewport.left = x1;
- viewport32767.left = x1 + 32768;
- viewport.top = y1;
- viewport32767.top = y1 + 32768;
- viewport.right = x2;
- viewport32767.right = x2 + 32768;
- viewport.bottom = y2;
- viewport32767.bottom = y2 + 32768;
- }
-
- void midlleline(int x1,int y1,int x2,int y2)
- {
- int i;
- if (abs(x2-x1) > abs(y2-y1)) //lo slope
- for(i=0;i<=linetype.width-1;i++) normalline(x1,y1+i,x2,y2+i);
- else //hi slope
- for(i=0;i<=linetype.width-1;i++) normalline(x1+i,y1,x2+i,y2);
- }
-
- void putpixel(int x,int y,BYTE color)
- {
- if (clippixel(x,y) == 0)
- asm {
- push ds
- mov ax,SEG proctable
- mov ds,ax
- lea si,proctable
- les si,[si]
- mov al,color
- push ax
- push cx
- push dx
- call dword ptr es:[si+indexputpixel*4]
- add sp,6
- pop ds
- }
- }
-
- BYTE getpixel(int x,int y)
- {
- asm {
- push ds
- mov ax,SEG proctable
- mov ds,ax
- lea si,proctable
- les si,[si]
- push y
- push x
- call dword ptr es:[si+indexgetpixel*4]
- add sp,4
- pop ds
- }
- }
-
- void moveto(int x,int y)
- {
- currx = x;
- curry = y;
- }
-
- void moverel(int dx,int dy)
- {
- currx+=dx;
- curry+=dy;
- }
-
- void rectangle(int x1,int y1,int x2,int y2)
- {
- line(x1,y1,x2,y1);
- line(x2,y1,x2,y2);
- line(x2,y2,x1,y2);
- line(x1,y1,x1,y2);
- }
-
- void lineto(int x,int y)
- {
- line(currx,curry,x,y);
- currx = x;
- curry = y;
- }
-
- void linerel(int dx,int dy)
- {
- line(currx,curry,currx+dx,curry+dy);
- currx+=dx;
- curry+=dy;
- }
-
- int getmaxx(void) {return(activemode.width-1);}
-
- int getmaxy(void) {return(activemode.height-1);}
-
- void setwritemode(BYTE wrmode)
- {
- if ((wrmode <= OR_PUT) && (wrmode != writemode))
- {
- writemode = wrmode;
- asm {
- push ds
- mov ax,SEG proctable
- mov ds,ax
- lea si,proctable
- les si,[si]
- mov ah,wrmode
- call dword ptr es:[si+indexchangeput*4]
- pop ds
- }
- }
- }
-
- void bar(int x,int y,int x1,int y1)
- {
- asm {
- push ds
- mov ax,SEG proctable
- mov ds,ax
- lea si,proctable
- les si,[si]
- push y1
- push x1
- push y
- push x
- call dword ptr es:[si+indexbar*4]
- add sp,8
- pop ds
- }
- }
-
- void putrow(rowptr row,int x,int y,int xcount)
- {
- asm {
- push ds
- mov ax,SEG proctable
- mov ds,ax
- lea si,proctable
- les si,[si]
- push xcount
- push y
- push x
- mov ax,word ptr row[2]
- push ax
- mov ax,word ptr row
- push ax
- call dword ptr es:[si+indexputrow*4]
- add sp,10
- pop ds
- }
- }
-
- void setlinestyle(WORD linestyle,WORD pattern,BYTE wline)
- {
- linetype.linestyle = linestyle;
- linetype.pattern = pattern;
- linetype.width = wline;
- switch (linestyle) {
- case SOLID_LINE : linepattern = solidline; break;
- case DOTTED_LINE : linepattern = dottedline; break;
- case CENTER_LINE : linepattern = centerline; break;
- case DASHED_LINE : linepattern = dashedline; break;
- default : USERBIT_LINE : linepattern = pattern;
- }
- switch (wline) {
- case NORM_WIDTH : line = normalline; break;
- case DOUBLE_WIDTH : line = midlleline; break;
- case THICK_WIDTH : line = midlleline; break;
- default : line = normalline;
- }
- }
-
- void setfillstyle(BYTE pattern,BYTE color)
- {
- if (pattern == USER_FILL) fillpatternptr = userpatternptr;
- else fillpatternptr = (BYTE*)MK_FP(FP_SEG(patterns[pattern]),
- FP_OFF(patterns[pattern]));
- fillcolor = color;
- patterntype = pattern;
- }
-
- void setfillpattern(BYTE* pattern) { userpatternptr = pattern;}
-
- void setcolor(BYTE color) {drawcolor = color;}
- BYTE getcolor(void) {return(drawcolor);}
- void setbkcolor(BYTE color) {backcolor = color;}
-
- void getimage(int x1,int y1,int x2,int y2,void* buffer)
- {
- asm {
- push ds
- mov ax,SEG proctable
- mov ds,ax
- lea si,proctable
- les si,[si]
- mov ax,word ptr buffer[2]
- push ax
- mov ax,word ptr buffer
- push ax
- push y2
- push x2
- push y1
- push x1
- call dword ptr es:[si+indexgetimage*4]
- add sp,12
- pop ds
- }
- }
-
- void putimage(int xo,int yo,void* buffer)
- {
- asm {
- push ds
- mov ax,SEG proctable
- mov ds,ax
- lea si,proctable
- les si,[si]
- mov ax,word ptr buffer[2]
- push ax
- mov ax,word ptr buffer
- push ax
- push yo
- push xo
- call dword ptr es:[si+indexputimage*4]
- add sp,8
- pop ds
- }
- }
-
- long imagesize(int x1,int y1,int x2,int y2)
- {
- asm {
- push ds
- mov ax,SEG proctable
- mov ds,ax
- lea si,proctable
- les si,[si]
- push y2
- push x2
- push y1
- push x1
- call dword ptr es:[si+indeximagesize*4]
- add sp,8
- pop ds
- }
- }
-
- void setglassflag(BYTE glflag) {trflag = glflag;}
-
- void closegraph(void)
- {
- asm {
- mov ah,0
- mov al,oldmode
- int 0x10
- }
- free(ArrayScanLinesPtr);
- }
-
- void circle(int x,int y,WORD radius) {ellipse(x,y,radius,radius);}
-
- void put4pixels(int xo,int yo,int x,int y)
- {
- putpixel(xo+x,yo+y,drawcolor);
- putpixel(xo-x,yo+y,drawcolor);
- putpixel(xo+x,yo-y,drawcolor);
- putpixel(xo-x,yo-y,drawcolor);
- }
-
- void ellipse(int xo,int yo,WORD xradius,WORD yradius)
- {
- int x = 0 ,y = yradius;
- long a = xradius,b = y;
- long asquared = a*a,twoasquared = 2*asquared;
- long bsquared = b*b,twobsquared = 2*bsquared;
- long d = bsquared - asquared*b + asquared/4;
- long dx = 0,dy = twoasquared*b;
- while (dx < dy)
- {
- put4pixels(xo,yo,x,y);
- if (d > 0)
- {
- y--;
- dy-=twoasquared;
- d-=dy;
- }
- x++;
- dx+=twobsquared;
- d = d+bsquared+dx;
- }
- d = (3*(asquared-bsquared)/2 -(dx+dy))/2;
- while (y >= 0)
- {
- put4pixels(xo,yo,x,y);
- if (d < 0)
- {
- x++;
- dx+=twobsquared;
- d+=dx;
- }
- y--;
- dy-=twoasquared;
- d = d-asquared - dy;
- }
- }
-